﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using Autofac;

namespace ShuttleBus
{
    internal class DynamicMessageHandler : IHandleMessages
    {
        private IEnumerable<IHandle<TService>> ResolveHandlers<TService>(ILifetimeScope lifetimeScope) where TService : Message
        {
            return lifetimeScope.Resolve<IEnumerable<IHandle<TService>>>();
        }

        public void HandleMessage(object message)
        {
            using (var lifetimeScope = UnitOfWork.Instance.CreateUnitOfWorkContainer())
            {
                Type messageType = message.GetType();

                var methodInfo = GetType().GetMethod("ResolveHandlers", BindingFlags.NonPublic | BindingFlags.Instance);
                var genericMethod = methodInfo.MakeGenericMethod(messageType);

                var handlers = genericMethod.Invoke(this, new[] { lifetimeScope }) as IEnumerable;

                if (handlers != null)
                {
                    foreach (var handler in handlers)
                    {
                        Type handlerType = handler.GetType();

                        var method = handlerType.GetMethod("Handle", new[] { messageType });
                        if (method != null)
                        {
                            method.Invoke(handler, new[] { message });
                        }
                    }
                }
            }
        }
    }
}